
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_Hans">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Database access optimization &#8212; Django 3.2.6.dev 文档</title>
    <link rel="stylesheet" href="../../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
    <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../../_static/jquery.js"></script>
    <script type="text/javascript" src="../../_static/underscore.js"></script>
    <script type="text/javascript" src="../../_static/doctools.js"></script>
    <script type="text/javascript" src="../../_static/language_data.js"></script>
    <link rel="index" title="索引" href="../../genindex.html" />
    <link rel="search" title="搜索" href="../../search.html" />
    <link rel="next" title="Database instrumentation" href="instrumentation.html" />
    <link rel="prev" title="Tablespaces" href="tablespaces.html" />



 
<script src="../../templatebuiltins.js"></script>
<script>
(function($) {
    if (!django_template_builtins) {
       // templatebuiltins.js missing, do nothing.
       return;
    }
    $(document).ready(function() {
        // Hyperlink Django template tags and filters
        var base = "../../ref/templates/builtins.html";
        if (base == "#") {
            // Special case for builtins.html itself
            base = "";
        }
        // Tags are keywords, class '.k'
        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
             var tagname = $(elem).text();
             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
                 var fragment = tagname.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
             }
        });
        // Filters are functions, class '.nf'
        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
             var filtername = $(elem).text();
             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
                 var fragment = filtername.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
             }
        });
    });
})(jQuery);</script>

  </head><body>

    <div class="document">
  <div id="custom-doc" class="yui-t6">
    <div id="hd">
      <h1><a href="../../index.html">Django 3.2.6.dev 文档</a></h1>
      <div id="global-nav">
        <a title="Home page" href="../../index.html">Home</a>  |
        <a title="Table of contents" href="../../contents.html">Table of contents</a>  |
        <a title="Global index" href="../../genindex.html">Index</a>  |
        <a title="Module index" href="../../py-modindex.html">Modules</a>
      </div>
      <div class="nav">
    &laquo; <a href="tablespaces.html" title="Tablespaces">previous</a>
     |
    <a href="../index.html" title="Using Django" accesskey="U">up</a>
   |
    <a href="instrumentation.html" title="Database instrumentation">next</a> &raquo;</div>
    </div>

    <div id="bd">
      <div id="yui-main">
        <div class="yui-b">
          <div class="yui-g" id="topics-db-optimization">
            
  <div class="section" id="s-database-access-optimization">
<span id="database-access-optimization"></span><h1>Database access optimization<a class="headerlink" href="#database-access-optimization" title="永久链接至标题">¶</a></h1>
<p>Django's database layer provides various ways to help developers get the most
out of their databases. This document gathers together links to the relevant
documentation, and adds various tips, organized under a number of headings that
outline the steps to take when attempting to optimize your database usage.</p>
<div class="section" id="s-profile-first">
<span id="profile-first"></span><h2>Profile first<a class="headerlink" href="#profile-first" title="永久链接至标题">¶</a></h2>
<p>As general programming practice, this goes without saying. Find out <a class="reference internal" href="../../faq/models.html#faq-see-raw-sql-queries"><span class="std std-ref">what
queries you are doing and what they are costing you</span></a>.
Use <a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.explain" title="django.db.models.query.QuerySet.explain"><code class="xref py py-meth docutils literal notranslate"><span class="pre">QuerySet.explain()</span></code></a> to understand how specific <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>s are
executed by your database. You may also want to use an external project like
<a class="reference external" href="https://github.com/jazzband/django-debug-toolbar/">django-debug-toolbar</a>, or a tool that monitors your database directly.</p>
<p>Remember that you may be optimizing for speed or memory or both, depending on
your requirements. Sometimes optimizing for one will be detrimental to the
other, but sometimes they will help each other. Also, work that is done by the
database process might not have the same cost (to you) as the same amount of
work done in your Python process. It is up to you to decide what your
priorities are, where the balance must lie, and profile all of these as required
since this will depend on your application and server.</p>
<p>With everything that follows, remember to profile after every change to ensure
that the change is a benefit, and a big enough benefit given the decrease in
readability of your code. <strong>All</strong> of the suggestions below come with the caveat
that in your circumstances the general principle might not apply, or might even
be reversed.</p>
</div>
<div class="section" id="s-use-standard-db-optimization-techniques">
<span id="use-standard-db-optimization-techniques"></span><h2>Use standard DB optimization techniques<a class="headerlink" href="#use-standard-db-optimization-techniques" title="永久链接至标题">¶</a></h2>
<p>...including:</p>
<ul class="simple">
<li><a class="reference external" href="https://en.wikipedia.org/wiki/Database_index">Indexes</a>. This is a number one priority, <em>after</em> you have determined from
profiling what indexes should be added. Use
<a class="reference internal" href="../../ref/models/options.html#django.db.models.Options.indexes" title="django.db.models.Options.indexes"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Meta.indexes</span></code></a> or
<a class="reference internal" href="../../ref/models/fields.html#django.db.models.Field.db_index" title="django.db.models.Field.db_index"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Field.db_index</span></code></a> to add these from
Django. Consider adding indexes to fields that you frequently query using
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.filter" title="django.db.models.query.QuerySet.filter"><code class="xref py py-meth docutils literal notranslate"><span class="pre">filter()</span></code></a>,
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.exclude" title="django.db.models.query.QuerySet.exclude"><code class="xref py py-meth docutils literal notranslate"><span class="pre">exclude()</span></code></a>,
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.order_by" title="django.db.models.query.QuerySet.order_by"><code class="xref py py-meth docutils literal notranslate"><span class="pre">order_by()</span></code></a>, etc. as indexes may help
to speed up lookups. Note that determining the best indexes is a complex
database-dependent topic that will depend on your particular application.
The overhead of maintaining an index may outweigh any gains in query speed.</li>
</ul>
<ul class="simple">
<li>Appropriate use of field types.</li>
</ul>
<p>We will assume you have done the things listed above. The rest of this document
focuses on how to use Django in such a way that you are not doing unnecessary
work. This document also does not address other optimization techniques that
apply to all expensive operations, such as <a class="reference internal" href="../cache.html"><span class="doc">general purpose caching</span></a>.</p>
</div>
<div class="section" id="s-understand-querysets">
<span id="understand-querysets"></span><h2>Understand <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>s<a class="headerlink" href="#understand-querysets" title="永久链接至标题">¶</a></h2>
<p>Understanding <a class="reference internal" href="../../ref/models/querysets.html"><span class="doc">QuerySets</span></a> is vital to getting good
performance with simple code. In particular:</p>
<div class="section" id="s-understand-queryset-evaluation">
<span id="understand-queryset-evaluation"></span><h3>Understand <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> evaluation<a class="headerlink" href="#understand-queryset-evaluation" title="永久链接至标题">¶</a></h3>
<p>To avoid performance problems, it is important to understand:</p>
<ul class="simple">
<li>that <a class="reference internal" href="queries.html#querysets-are-lazy"><span class="std std-ref">QuerySets are lazy</span></a>.</li>
<li>when <a class="reference internal" href="../../ref/models/querysets.html#when-querysets-are-evaluated"><span class="std std-ref">they are evaluated</span></a>.</li>
<li>how <a class="reference internal" href="queries.html#caching-and-querysets"><span class="std std-ref">the data is held in memory</span></a>.</li>
</ul>
</div>
<div class="section" id="s-understand-cached-attributes">
<span id="understand-cached-attributes"></span><h3>Understand cached attributes<a class="headerlink" href="#understand-cached-attributes" title="永久链接至标题">¶</a></h3>
<p>As well as caching of the whole <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>, there is caching of the result of
attributes on ORM objects. In general, attributes that are not callable will be
cached. For example, assuming the <a class="reference internal" href="queries.html#queryset-model-example"><span class="std std-ref">example Weblog models</span></a>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">entry</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">entry</span><span class="o">.</span><span class="n">blog</span>   <span class="c1"># Blog object is retrieved at this point</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">entry</span><span class="o">.</span><span class="n">blog</span>   <span class="c1"># cached version, no DB access</span>
</pre></div>
</div>
<p>But in general, callable attributes cause DB lookups every time:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">entry</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">entry</span><span class="o">.</span><span class="n">authors</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>   <span class="c1"># query performed</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">entry</span><span class="o">.</span><span class="n">authors</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>   <span class="c1"># query performed again</span>
</pre></div>
</div>
<p>Be careful when reading template code - the template system does not allow use
of parentheses, but will call callables automatically, hiding the above
distinction.</p>
<p>Be careful with your own custom properties - it is up to you to implement
caching when required, for example using the
<a class="reference internal" href="../../ref/utils.html#django.utils.functional.cached_property" title="django.utils.functional.cached_property"><code class="xref py py-class docutils literal notranslate"><span class="pre">cached_property</span></code></a> decorator.</p>
</div>
<div class="section" id="s-use-the-with-template-tag">
<span id="use-the-with-template-tag"></span><h3>Use the <code class="docutils literal notranslate"><span class="pre">with</span></code> template tag<a class="headerlink" href="#use-the-with-template-tag" title="永久链接至标题">¶</a></h3>
<p>To make use of the caching behavior of <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>, you may need to use the
<a class="reference internal" href="../../ref/templates/builtins.html#std:templatetag-with"><code class="xref std std-ttag docutils literal notranslate"><span class="pre">with</span></code></a> template tag.</p>
</div>
<div class="section" id="s-use-iterator">
<span id="use-iterator"></span><h3>Use <code class="docutils literal notranslate"><span class="pre">iterator()</span></code><a class="headerlink" href="#use-iterator" title="永久链接至标题">¶</a></h3>
<p>When you have a lot of objects, the caching behavior of the <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> can
cause a large amount of memory to be used. In this case,
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.iterator" title="django.db.models.query.QuerySet.iterator"><code class="xref py py-meth docutils literal notranslate"><span class="pre">iterator()</span></code></a> may help.</p>
</div>
<div class="section" id="s-use-explain">
<span id="use-explain"></span><h3>Use <code class="docutils literal notranslate"><span class="pre">explain()</span></code><a class="headerlink" href="#use-explain" title="永久链接至标题">¶</a></h3>
<p><a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.explain" title="django.db.models.query.QuerySet.explain"><code class="xref py py-meth docutils literal notranslate"><span class="pre">QuerySet.explain()</span></code></a> gives you detailed information about how the database
executes a query, including indexes and joins that are used. These details may
help you find queries that could be rewritten more efficiently, or identify
indexes that could be added to improve performance.</p>
</div>
</div>
<div class="section" id="s-do-database-work-in-the-database-rather-than-in-python">
<span id="do-database-work-in-the-database-rather-than-in-python"></span><h2>Do database work in the database rather than in Python<a class="headerlink" href="#do-database-work-in-the-database-rather-than-in-python" title="永久链接至标题">¶</a></h2>
<p>For instance:</p>
<ul class="simple">
<li>At the most basic level, use <a class="reference internal" href="../../ref/models/querysets.html#queryset-api"><span class="std std-ref">filter and exclude</span></a> to do
filtering in the database.</li>
<li>Use <a class="reference internal" href="../../ref/models/expressions.html#django.db.models.F" title="django.db.models.F"><code class="xref py py-class docutils literal notranslate"><span class="pre">F</span> <span class="pre">expressions</span></code></a> to filter
based on other fields within the same model.</li>
<li>Use <a class="reference internal" href="aggregation.html"><span class="doc">annotate to do aggregation in the database</span></a>.</li>
</ul>
<p>If these aren't enough to generate the SQL you need:</p>
<div class="section" id="s-use-rawsql">
<span id="use-rawsql"></span><h3>Use <code class="docutils literal notranslate"><span class="pre">RawSQL</span></code><a class="headerlink" href="#use-rawsql" title="永久链接至标题">¶</a></h3>
<p>A less portable but more powerful method is the
<a class="reference internal" href="../../ref/models/expressions.html#django.db.models.expressions.RawSQL" title="django.db.models.expressions.RawSQL"><code class="xref py py-class docutils literal notranslate"><span class="pre">RawSQL</span></code></a> expression, which allows some SQL
to be explicitly added to the query. If that still isn't powerful enough:</p>
</div>
<div class="section" id="s-use-raw-sql">
<span id="use-raw-sql"></span><h3>Use raw SQL<a class="headerlink" href="#use-raw-sql" title="永久链接至标题">¶</a></h3>
<p>Write your own <a class="reference internal" href="sql.html"><span class="doc">custom SQL to retrieve data or populate models</span></a>. Use <code class="docutils literal notranslate"><span class="pre">django.db.connection.queries</span></code> to find out what Django
is writing for you and start from there.</p>
</div>
</div>
<div class="section" id="s-retrieve-individual-objects-using-a-unique-indexed-column">
<span id="retrieve-individual-objects-using-a-unique-indexed-column"></span><h2>Retrieve individual objects using a unique, indexed column<a class="headerlink" href="#retrieve-individual-objects-using-a-unique-indexed-column" title="永久链接至标题">¶</a></h2>
<p>There are two reasons to use a column with
<a class="reference internal" href="../../ref/models/fields.html#django.db.models.Field.unique" title="django.db.models.Field.unique"><code class="xref py py-attr docutils literal notranslate"><span class="pre">unique</span></code></a> or
<a class="reference internal" href="../../ref/models/fields.html#django.db.models.Field.db_index" title="django.db.models.Field.db_index"><code class="xref py py-attr docutils literal notranslate"><span class="pre">db_index</span></code></a> when using
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.get" title="django.db.models.query.QuerySet.get"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get()</span></code></a> to retrieve individual objects.
First, the query will be quicker because of the underlying database index.
Also, the query could run much slower if multiple objects match the lookup;
having a unique constraint on the column guarantees this will never happen.</p>
<p>So using the <a class="reference internal" href="queries.html#queryset-model-example"><span class="std std-ref">example Weblog models</span></a>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">entry</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
</pre></div>
</div>
<p>will be quicker than:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">entry</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">headline</span><span class="o">=</span><span class="s2">&quot;News Item Title&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>because <code class="docutils literal notranslate"><span class="pre">id</span></code> is indexed by the database and is guaranteed to be unique.</p>
<p>Doing the following is potentially quite slow:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">entry</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">headline__startswith</span><span class="o">=</span><span class="s2">&quot;News&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>First of all, <code class="docutils literal notranslate"><span class="pre">headline</span></code> is not indexed, which will make the underlying
database fetch slower.</p>
<p>Second, the lookup doesn't guarantee that only one object will be returned.
If the query matches more than one object, it will retrieve and transfer all of
them from the database. This penalty could be substantial if hundreds or
thousands of records are returned. The penalty will be compounded if the
database lives on a separate server, where network overhead and latency also
play a factor.</p>
</div>
<div class="section" id="s-retrieve-everything-at-once-if-you-know-you-will-need-it">
<span id="retrieve-everything-at-once-if-you-know-you-will-need-it"></span><h2>Retrieve everything at once if you know you will need it<a class="headerlink" href="#retrieve-everything-at-once-if-you-know-you-will-need-it" title="永久链接至标题">¶</a></h2>
<p>Hitting the database multiple times for different parts of a single 'set' of
data that you will need all parts of is, in general, less efficient than
retrieving it all in one query. This is particularly important if you have a
query that is executed in a loop, and could therefore end up doing many database
queries, when only one was needed. So:</p>
<div class="section" id="s-use-queryset-select-related-and-prefetch-related">
<span id="use-queryset-select-related-and-prefetch-related"></span><h3>Use <code class="docutils literal notranslate"><span class="pre">QuerySet.select_related()</span></code> and <code class="docutils literal notranslate"><span class="pre">prefetch_related()</span></code><a class="headerlink" href="#use-queryset-select-related-and-prefetch-related" title="永久链接至标题">¶</a></h3>
<p>Understand <a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.select_related" title="django.db.models.query.QuerySet.select_related"><code class="xref py py-meth docutils literal notranslate"><span class="pre">select_related()</span></code></a> and
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.prefetch_related" title="django.db.models.query.QuerySet.prefetch_related"><code class="xref py py-meth docutils literal notranslate"><span class="pre">prefetch_related()</span></code></a> thoroughly, and use
them:</p>
<ul class="simple">
<li>in <a class="reference internal" href="managers.html"><span class="doc">managers and default managers</span></a> where
appropriate. Be aware when your manager is and is not used; sometimes this is
tricky so don't make assumptions.</li>
<li>in view code or other layers, possibly making use of
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.prefetch_related_objects" title="django.db.models.prefetch_related_objects"><code class="xref py py-func docutils literal notranslate"><span class="pre">prefetch_related_objects()</span></code></a> where needed.</li>
</ul>
</div>
</div>
<div class="section" id="s-don-t-retrieve-things-you-don-t-need">
<span id="don-t-retrieve-things-you-don-t-need"></span><h2>Don't retrieve things you don't need<a class="headerlink" href="#don-t-retrieve-things-you-don-t-need" title="永久链接至标题">¶</a></h2>
<div class="section" id="s-use-queryset-values-and-values-list">
<span id="use-queryset-values-and-values-list"></span><h3>Use <code class="docutils literal notranslate"><span class="pre">QuerySet.values()</span></code> and <code class="docutils literal notranslate"><span class="pre">values_list()</span></code><a class="headerlink" href="#use-queryset-values-and-values-list" title="永久链接至标题">¶</a></h3>
<p>When you only want a <code class="docutils literal notranslate"><span class="pre">dict</span></code> or <code class="docutils literal notranslate"><span class="pre">list</span></code> of values, and don't need ORM model
objects, make appropriate usage of
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.values" title="django.db.models.query.QuerySet.values"><code class="xref py py-meth docutils literal notranslate"><span class="pre">values()</span></code></a>.
These can be useful for replacing model objects in template code - as long as
the dicts you supply have the same attributes as those used in the template,
you are fine.</p>
</div>
<div class="section" id="s-use-queryset-defer-and-only">
<span id="use-queryset-defer-and-only"></span><h3>Use <code class="docutils literal notranslate"><span class="pre">QuerySet.defer()</span></code> and <code class="docutils literal notranslate"><span class="pre">only()</span></code><a class="headerlink" href="#use-queryset-defer-and-only" title="永久链接至标题">¶</a></h3>
<p>Use <a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.defer" title="django.db.models.query.QuerySet.defer"><code class="xref py py-meth docutils literal notranslate"><span class="pre">defer()</span></code></a> and
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.only" title="django.db.models.query.QuerySet.only"><code class="xref py py-meth docutils literal notranslate"><span class="pre">only()</span></code></a> if there are database columns
you know that you won't need (or won't need in most cases) to avoid loading
them. Note that if you <em>do</em> use them, the ORM will have to go and get them in
a separate query, making this a pessimization if you use it inappropriately.</p>
<p>Don't be too aggressive in deferring fields without profiling as the database
has to read most of the non-text, non-VARCHAR data from the disk for a single
row in the results, even if it ends up only using a few columns. The
<code class="docutils literal notranslate"><span class="pre">defer()</span></code> and <code class="docutils literal notranslate"><span class="pre">only()</span></code> methods are most useful when you can avoid loading a
lot of text data or for fields that might take a lot of processing to convert
back to Python. As always, profile first, then optimize.</p>
</div>
<div class="section" id="s-use-queryset-count">
<span id="use-queryset-count"></span><h3>Use <code class="docutils literal notranslate"><span class="pre">QuerySet.count()</span></code><a class="headerlink" href="#use-queryset-count" title="永久链接至标题">¶</a></h3>
<p>...if you only want the count, rather than doing <code class="docutils literal notranslate"><span class="pre">len(queryset)</span></code>.</p>
</div>
<div class="section" id="s-use-queryset-exists">
<span id="use-queryset-exists"></span><h3>Use <code class="docutils literal notranslate"><span class="pre">QuerySet.exists()</span></code><a class="headerlink" href="#use-queryset-exists" title="永久链接至标题">¶</a></h3>
<p>...if you only want to find out if at least one result exists, rather than <code class="docutils literal notranslate"><span class="pre">if</span>
<span class="pre">queryset</span></code>.</p>
<p>But:</p>
</div>
<div class="section" id="s-don-t-overuse-count-and-exists">
<span id="s-overuse-of-count-and-exists"></span><span id="don-t-overuse-count-and-exists"></span><span id="overuse-of-count-and-exists"></span><h3>Don't overuse <code class="docutils literal notranslate"><span class="pre">count()</span></code> and <code class="docutils literal notranslate"><span class="pre">exists()</span></code><a class="headerlink" href="#don-t-overuse-count-and-exists" title="永久链接至标题">¶</a></h3>
<p>If you are going to need other data from the QuerySet, evaluate it immediately.</p>
<p>For example, assuming an Email model that has a <code class="docutils literal notranslate"><span class="pre">subject</span></code> attribute and a
many-to-many relation to User, the following code is optimal:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">display_emails</span><span class="p">:</span>
    <span class="n">emails</span> <span class="o">=</span> <span class="n">user</span><span class="o">.</span><span class="n">emails</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
    <span class="k">if</span> <span class="n">emails</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;You have&#39;</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">emails</span><span class="p">),</span> <span class="s1">&#39;emails:&#39;</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">email</span> <span class="ow">in</span> <span class="n">emails</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="n">email</span><span class="o">.</span><span class="n">subject</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;You do not have any emails.&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>It is optimal because:</p>
<ol class="arabic simple">
<li>Since QuerySets are lazy, this does no database queries if
<code class="docutils literal notranslate"><span class="pre">display_emails</span></code> is <code class="docutils literal notranslate"><span class="pre">False</span></code>.</li>
<li>Storing <code class="docutils literal notranslate"><span class="pre">user.emails.all()</span></code> in the <code class="docutils literal notranslate"><span class="pre">emails</span></code> variable allows its result
cache to be re-used.</li>
<li>The line <code class="docutils literal notranslate"><span class="pre">if</span> <span class="pre">emails</span></code> causes <code class="docutils literal notranslate"><span class="pre">QuerySet.__bool__()</span></code> to be called, which
causes the <code class="docutils literal notranslate"><span class="pre">user.emails.all()</span></code> query to be run on the database. If there
aren't any results, it will return <code class="docutils literal notranslate"><span class="pre">False</span></code>, otherwise <code class="docutils literal notranslate"><span class="pre">True</span></code>.</li>
<li>The use of <code class="docutils literal notranslate"><span class="pre">len(emails)</span></code> calls <code class="docutils literal notranslate"><span class="pre">QuerySet.__len__()</span></code>, reusing the result
cache.</li>
<li>The <code class="docutils literal notranslate"><span class="pre">for</span></code> loop iterates over the already filled cache.</li>
</ol>
<p>In total, this code does either one or zero database queries. The only
deliberate optimization performed is using the <code class="docutils literal notranslate"><span class="pre">emails</span></code> variable. Using
<code class="docutils literal notranslate"><span class="pre">QuerySet.exists()</span></code> for the <code class="docutils literal notranslate"><span class="pre">if</span></code> or <code class="docutils literal notranslate"><span class="pre">QuerySet.count()</span></code> for the count
would each cause additional queries.</p>
</div>
<div class="section" id="s-use-queryset-update-and-delete">
<span id="use-queryset-update-and-delete"></span><h3>Use <code class="docutils literal notranslate"><span class="pre">QuerySet.update()</span></code> and <code class="docutils literal notranslate"><span class="pre">delete()</span></code><a class="headerlink" href="#use-queryset-update-and-delete" title="永久链接至标题">¶</a></h3>
<p>Rather than retrieve a load of objects, set some values, and save them
individual, use a bulk SQL UPDATE statement, via <a class="reference internal" href="queries.html#topics-db-queries-update"><span class="std std-ref">QuerySet.update()</span></a>. Similarly, do <a class="reference internal" href="queries.html#topics-db-queries-delete"><span class="std std-ref">bulk deletes</span></a> where possible.</p>
<p>Note, however, that these bulk update methods cannot call the <code class="docutils literal notranslate"><span class="pre">save()</span></code> or
<code class="docutils literal notranslate"><span class="pre">delete()</span></code> methods of individual instances, which means that any custom
behavior you have added for these methods will not be executed, including
anything driven from the normal database object <a class="reference internal" href="../../ref/signals.html"><span class="doc">signals</span></a>.</p>
</div>
<div class="section" id="s-use-foreign-key-values-directly">
<span id="use-foreign-key-values-directly"></span><h3>Use foreign key values directly<a class="headerlink" href="#use-foreign-key-values-directly" title="永久链接至标题">¶</a></h3>
<p>If you only need a foreign key value, use the foreign key value that is already on
the object you've got, rather than getting the whole related object and taking
its primary key. i.e. do:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">entry</span><span class="o">.</span><span class="n">blog_id</span>
</pre></div>
</div>
<p>instead of:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">entry</span><span class="o">.</span><span class="n">blog</span><span class="o">.</span><span class="n">id</span>
</pre></div>
</div>
</div>
<div class="section" id="s-don-t-order-results-if-you-don-t-care">
<span id="don-t-order-results-if-you-don-t-care"></span><h3>Don't order results if you don't care<a class="headerlink" href="#don-t-order-results-if-you-don-t-care" title="永久链接至标题">¶</a></h3>
<p>Ordering is not free; each field to order by is an operation the database must
perform. If a model has a default ordering (<a class="reference internal" href="../../ref/models/options.html#django.db.models.Options.ordering" title="django.db.models.Options.ordering"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Meta.ordering</span></code></a>) and you don't need it, remove
it on a <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> by calling
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.order_by" title="django.db.models.query.QuerySet.order_by"><code class="xref py py-meth docutils literal notranslate"><span class="pre">order_by()</span></code></a> with no parameters.</p>
<p>Adding an index to your database may help to improve ordering performance.</p>
</div>
</div>
<div class="section" id="s-use-bulk-methods">
<span id="use-bulk-methods"></span><h2>Use bulk methods<a class="headerlink" href="#use-bulk-methods" title="永久链接至标题">¶</a></h2>
<p>Use bulk methods to reduce the number of SQL statements.</p>
<div class="section" id="s-create-in-bulk">
<span id="create-in-bulk"></span><h3>Create in bulk<a class="headerlink" href="#create-in-bulk" title="永久链接至标题">¶</a></h3>
<p>When creating objects, where possible, use the
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.bulk_create" title="django.db.models.query.QuerySet.bulk_create"><code class="xref py py-meth docutils literal notranslate"><span class="pre">bulk_create()</span></code></a> method to reduce the
number of SQL queries. For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">bulk_create</span><span class="p">([</span>
    <span class="n">Entry</span><span class="p">(</span><span class="n">headline</span><span class="o">=</span><span class="s1">&#39;This is a test&#39;</span><span class="p">),</span>
    <span class="n">Entry</span><span class="p">(</span><span class="n">headline</span><span class="o">=</span><span class="s1">&#39;This is only a test&#39;</span><span class="p">),</span>
<span class="p">])</span>
</pre></div>
</div>
<p>...is preferable to:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">headline</span><span class="o">=</span><span class="s1">&#39;This is a test&#39;</span><span class="p">)</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">headline</span><span class="o">=</span><span class="s1">&#39;This is only a test&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>Note that there are a number of <a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.bulk_create" title="django.db.models.query.QuerySet.bulk_create"><code class="xref py py-meth docutils literal notranslate"><span class="pre">caveats</span> <span class="pre">to</span> <span class="pre">this</span> <span class="pre">method</span></code></a>, so make sure it's appropriate
for your use case.</p>
</div>
<div class="section" id="s-update-in-bulk">
<span id="update-in-bulk"></span><h3>Update in bulk<a class="headerlink" href="#update-in-bulk" title="永久链接至标题">¶</a></h3>
<p>When updating objects, where possible, use the
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.bulk_update" title="django.db.models.query.QuerySet.bulk_update"><code class="xref py py-meth docutils literal notranslate"><span class="pre">bulk_update()</span></code></a> method to reduce the
number of SQL queries. Given a list or queryset of objects:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">entries</span> <span class="o">=</span> <span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">bulk_create</span><span class="p">([</span>
    <span class="n">Entry</span><span class="p">(</span><span class="n">headline</span><span class="o">=</span><span class="s1">&#39;This is a test&#39;</span><span class="p">),</span>
    <span class="n">Entry</span><span class="p">(</span><span class="n">headline</span><span class="o">=</span><span class="s1">&#39;This is only a test&#39;</span><span class="p">),</span>
<span class="p">])</span>
</pre></div>
</div>
<p>The following example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">entries</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">headline</span> <span class="o">=</span> <span class="s1">&#39;This is not a test&#39;</span>
<span class="n">entries</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">headline</span> <span class="o">=</span> <span class="s1">&#39;This is no longer a test&#39;</span>
<span class="n">Entry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">bulk_update</span><span class="p">(</span><span class="n">entries</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;headline&#39;</span><span class="p">])</span>
</pre></div>
</div>
<p>...is preferable to:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">entries</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">headline</span> <span class="o">=</span> <span class="s1">&#39;This is not a test&#39;</span>
<span class="n">entries</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
<span class="n">entries</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">headline</span> <span class="o">=</span> <span class="s1">&#39;This is no longer a test&#39;</span>
<span class="n">entries</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
</pre></div>
</div>
<p>Note that there are a number of <a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.bulk_update" title="django.db.models.query.QuerySet.bulk_update"><code class="xref py py-meth docutils literal notranslate"><span class="pre">caveats</span> <span class="pre">to</span> <span class="pre">this</span> <span class="pre">method</span></code></a>, so make sure it's appropriate
for your use case.</p>
</div>
<div class="section" id="s-insert-in-bulk">
<span id="insert-in-bulk"></span><h3>Insert in bulk<a class="headerlink" href="#insert-in-bulk" title="永久链接至标题">¶</a></h3>
<p>When inserting objects into <a class="reference internal" href="../../ref/models/fields.html#django.db.models.ManyToManyField" title="django.db.models.ManyToManyField"><code class="xref py py-class docutils literal notranslate"><span class="pre">ManyToManyFields</span></code></a>, use
<a class="reference internal" href="../../ref/models/relations.html#django.db.models.fields.related.RelatedManager.add" title="django.db.models.fields.related.RelatedManager.add"><code class="xref py py-meth docutils literal notranslate"><span class="pre">add()</span></code></a> with multiple
objects to reduce the number of SQL queries. For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">my_band</span><span class="o">.</span><span class="n">members</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">me</span><span class="p">,</span> <span class="n">my_friend</span><span class="p">)</span>
</pre></div>
</div>
<p>...is preferable to:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">my_band</span><span class="o">.</span><span class="n">members</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">me</span><span class="p">)</span>
<span class="n">my_band</span><span class="o">.</span><span class="n">members</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">my_friend</span><span class="p">)</span>
</pre></div>
</div>
<p>...where <code class="docutils literal notranslate"><span class="pre">Bands</span></code> and <code class="docutils literal notranslate"><span class="pre">Artists</span></code> have a many-to-many relationship.</p>
<p>When inserting different pairs of objects into
<a class="reference internal" href="../../ref/models/fields.html#django.db.models.ManyToManyField" title="django.db.models.ManyToManyField"><code class="xref py py-class docutils literal notranslate"><span class="pre">ManyToManyField</span></code></a> or when the custom
<a class="reference internal" href="../../ref/models/fields.html#django.db.models.ManyToManyField.through" title="django.db.models.ManyToManyField.through"><code class="xref py py-attr docutils literal notranslate"><span class="pre">through</span></code></a> table is defined, use
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.bulk_create" title="django.db.models.query.QuerySet.bulk_create"><code class="xref py py-meth docutils literal notranslate"><span class="pre">bulk_create()</span></code></a> method to reduce the
number of SQL queries. For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">PizzaToppingRelationship</span> <span class="o">=</span> <span class="n">Pizza</span><span class="o">.</span><span class="n">toppings</span><span class="o">.</span><span class="n">through</span>
<span class="n">PizzaToppingRelationship</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">bulk_create</span><span class="p">([</span>
    <span class="n">PizzaToppingRelationship</span><span class="p">(</span><span class="n">pizza</span><span class="o">=</span><span class="n">my_pizza</span><span class="p">,</span> <span class="n">topping</span><span class="o">=</span><span class="n">pepperoni</span><span class="p">),</span>
    <span class="n">PizzaToppingRelationship</span><span class="p">(</span><span class="n">pizza</span><span class="o">=</span><span class="n">your_pizza</span><span class="p">,</span> <span class="n">topping</span><span class="o">=</span><span class="n">pepperoni</span><span class="p">),</span>
    <span class="n">PizzaToppingRelationship</span><span class="p">(</span><span class="n">pizza</span><span class="o">=</span><span class="n">your_pizza</span><span class="p">,</span> <span class="n">topping</span><span class="o">=</span><span class="n">mushroom</span><span class="p">),</span>
<span class="p">],</span> <span class="n">ignore_conflicts</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p>...is preferable to:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">my_pizza</span><span class="o">.</span><span class="n">toppings</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">pepperoni</span><span class="p">)</span>
<span class="n">your_pizza</span><span class="o">.</span><span class="n">toppings</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">pepperoni</span><span class="p">,</span> <span class="n">mushroom</span><span class="p">)</span>
</pre></div>
</div>
<p>...where <code class="docutils literal notranslate"><span class="pre">Pizza</span></code> and <code class="docutils literal notranslate"><span class="pre">Topping</span></code> have a many-to-many relationship. Note that
there are a number of <a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.bulk_create" title="django.db.models.query.QuerySet.bulk_create"><code class="xref py py-meth docutils literal notranslate"><span class="pre">caveats</span> <span class="pre">to</span> <span class="pre">this</span> <span class="pre">method</span></code></a>, so make sure it's appropriate
for your use case.</p>
</div>
<div class="section" id="s-remove-in-bulk">
<span id="remove-in-bulk"></span><h3>Remove in bulk<a class="headerlink" href="#remove-in-bulk" title="永久链接至标题">¶</a></h3>
<p>When removing objects from <a class="reference internal" href="../../ref/models/fields.html#django.db.models.ManyToManyField" title="django.db.models.ManyToManyField"><code class="xref py py-class docutils literal notranslate"><span class="pre">ManyToManyFields</span></code></a>, use
<a class="reference internal" href="../../ref/models/relations.html#django.db.models.fields.related.RelatedManager.remove" title="django.db.models.fields.related.RelatedManager.remove"><code class="xref py py-meth docutils literal notranslate"><span class="pre">remove()</span></code></a> with multiple
objects to reduce the number of SQL queries. For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">my_band</span><span class="o">.</span><span class="n">members</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">me</span><span class="p">,</span> <span class="n">my_friend</span><span class="p">)</span>
</pre></div>
</div>
<p>...is preferable to:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">my_band</span><span class="o">.</span><span class="n">members</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">me</span><span class="p">)</span>
<span class="n">my_band</span><span class="o">.</span><span class="n">members</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">my_friend</span><span class="p">)</span>
</pre></div>
</div>
<p>...where <code class="docutils literal notranslate"><span class="pre">Bands</span></code> and <code class="docutils literal notranslate"><span class="pre">Artists</span></code> have a many-to-many relationship.</p>
<p>When removing different pairs of objects from <a class="reference internal" href="../../ref/models/fields.html#django.db.models.ManyToManyField" title="django.db.models.ManyToManyField"><code class="xref py py-class docutils literal notranslate"><span class="pre">ManyToManyFields</span></code></a>, use
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet.delete" title="django.db.models.query.QuerySet.delete"><code class="xref py py-meth docutils literal notranslate"><span class="pre">delete()</span></code></a> on a
<a class="reference internal" href="../../ref/models/querysets.html#django.db.models.Q" title="django.db.models.Q"><code class="xref py py-class docutils literal notranslate"><span class="pre">Q</span></code></a> expression with multiple
<a class="reference internal" href="../../ref/models/fields.html#django.db.models.ManyToManyField.through" title="django.db.models.ManyToManyField.through"><code class="xref py py-attr docutils literal notranslate"><span class="pre">through</span></code></a>  model instances to reduce
the number of SQL queries. For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">django.db.models</span> <span class="kn">import</span> <span class="n">Q</span>
<span class="n">PizzaToppingRelationship</span> <span class="o">=</span> <span class="n">Pizza</span><span class="o">.</span><span class="n">toppings</span><span class="o">.</span><span class="n">through</span>
<span class="n">PizzaToppingRelationship</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span>
    <span class="n">Q</span><span class="p">(</span><span class="n">pizza</span><span class="o">=</span><span class="n">my_pizza</span><span class="p">,</span> <span class="n">topping</span><span class="o">=</span><span class="n">pepperoni</span><span class="p">)</span> <span class="o">|</span>
    <span class="n">Q</span><span class="p">(</span><span class="n">pizza</span><span class="o">=</span><span class="n">your_pizza</span><span class="p">,</span> <span class="n">topping</span><span class="o">=</span><span class="n">pepperoni</span><span class="p">)</span> <span class="o">|</span>
    <span class="n">Q</span><span class="p">(</span><span class="n">pizza</span><span class="o">=</span><span class="n">your_pizza</span><span class="p">,</span> <span class="n">topping</span><span class="o">=</span><span class="n">mushroom</span><span class="p">)</span>
<span class="p">)</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
</pre></div>
</div>
<p>...is preferable to:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">my_pizza</span><span class="o">.</span><span class="n">toppings</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">pepperoni</span><span class="p">)</span>
<span class="n">your_pizza</span><span class="o">.</span><span class="n">toppings</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">pepperoni</span><span class="p">,</span> <span class="n">mushroom</span><span class="p">)</span>
</pre></div>
</div>
<p>...where <code class="docutils literal notranslate"><span class="pre">Pizza</span></code> and <code class="docutils literal notranslate"><span class="pre">Topping</span></code> have a many-to-many relationship.</p>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      
        
          <div class="yui-b" id="sidebar">
            
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../../contents.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Database access optimization</a><ul>
<li><a class="reference internal" href="#profile-first">Profile first</a></li>
<li><a class="reference internal" href="#use-standard-db-optimization-techniques">Use standard DB optimization techniques</a></li>
<li><a class="reference internal" href="#understand-querysets">Understand <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code>s</a><ul>
<li><a class="reference internal" href="#understand-queryset-evaluation">Understand <code class="docutils literal notranslate"><span class="pre">QuerySet</span></code> evaluation</a></li>
<li><a class="reference internal" href="#understand-cached-attributes">Understand cached attributes</a></li>
<li><a class="reference internal" href="#use-the-with-template-tag">Use the <code class="docutils literal notranslate"><span class="pre">with</span></code> template tag</a></li>
<li><a class="reference internal" href="#use-iterator">Use <code class="docutils literal notranslate"><span class="pre">iterator()</span></code></a></li>
<li><a class="reference internal" href="#use-explain">Use <code class="docutils literal notranslate"><span class="pre">explain()</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#do-database-work-in-the-database-rather-than-in-python">Do database work in the database rather than in Python</a><ul>
<li><a class="reference internal" href="#use-rawsql">Use <code class="docutils literal notranslate"><span class="pre">RawSQL</span></code></a></li>
<li><a class="reference internal" href="#use-raw-sql">Use raw SQL</a></li>
</ul>
</li>
<li><a class="reference internal" href="#retrieve-individual-objects-using-a-unique-indexed-column">Retrieve individual objects using a unique, indexed column</a></li>
<li><a class="reference internal" href="#retrieve-everything-at-once-if-you-know-you-will-need-it">Retrieve everything at once if you know you will need it</a><ul>
<li><a class="reference internal" href="#use-queryset-select-related-and-prefetch-related">Use <code class="docutils literal notranslate"><span class="pre">QuerySet.select_related()</span></code> and <code class="docutils literal notranslate"><span class="pre">prefetch_related()</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#don-t-retrieve-things-you-don-t-need">Don't retrieve things you don't need</a><ul>
<li><a class="reference internal" href="#use-queryset-values-and-values-list">Use <code class="docutils literal notranslate"><span class="pre">QuerySet.values()</span></code> and <code class="docutils literal notranslate"><span class="pre">values_list()</span></code></a></li>
<li><a class="reference internal" href="#use-queryset-defer-and-only">Use <code class="docutils literal notranslate"><span class="pre">QuerySet.defer()</span></code> and <code class="docutils literal notranslate"><span class="pre">only()</span></code></a></li>
<li><a class="reference internal" href="#use-queryset-count">Use <code class="docutils literal notranslate"><span class="pre">QuerySet.count()</span></code></a></li>
<li><a class="reference internal" href="#use-queryset-exists">Use <code class="docutils literal notranslate"><span class="pre">QuerySet.exists()</span></code></a></li>
<li><a class="reference internal" href="#don-t-overuse-count-and-exists">Don't overuse <code class="docutils literal notranslate"><span class="pre">count()</span></code> and <code class="docutils literal notranslate"><span class="pre">exists()</span></code></a></li>
<li><a class="reference internal" href="#use-queryset-update-and-delete">Use <code class="docutils literal notranslate"><span class="pre">QuerySet.update()</span></code> and <code class="docutils literal notranslate"><span class="pre">delete()</span></code></a></li>
<li><a class="reference internal" href="#use-foreign-key-values-directly">Use foreign key values directly</a></li>
<li><a class="reference internal" href="#don-t-order-results-if-you-don-t-care">Don't order results if you don't care</a></li>
</ul>
</li>
<li><a class="reference internal" href="#use-bulk-methods">Use bulk methods</a><ul>
<li><a class="reference internal" href="#create-in-bulk">Create in bulk</a></li>
<li><a class="reference internal" href="#update-in-bulk">Update in bulk</a></li>
<li><a class="reference internal" href="#insert-in-bulk">Insert in bulk</a></li>
<li><a class="reference internal" href="#remove-in-bulk">Remove in bulk</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>上一个主题</h4>
  <p class="topless"><a href="tablespaces.html"
                        title="上一章">Tablespaces</a></p>
  <h4>下一个主题</h4>
  <p class="topless"><a href="instrumentation.html"
                        title="下一章">Database instrumentation</a></p>
  <div role="note" aria-label="source link">
    <h3>本页</h3>
    <ul class="this-page-menu">
      <li><a href="../../_sources/topics/db/optimization.txt"
            rel="nofollow">显示源代码</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3>快速搜索</h3>
    <div class="searchformwrapper">
    <form class="search" action="../../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="转向" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    </div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
              <h3>Last update:</h3>
              <p class="topless">7月 23, 2021</p>
          </div>
        
      
    </div>

    <div id="ft">
      <div class="nav">
    &laquo; <a href="tablespaces.html" title="Tablespaces">previous</a>
     |
    <a href="../index.html" title="Using Django" accesskey="U">up</a>
   |
    <a href="instrumentation.html" title="Database instrumentation">next</a> &raquo;</div>
    </div>
  </div>

      <div class="clearer"></div>
    </div>
  </body>
</html>